<template>
  <div class="container">
    <!-- 工具栏 -->
    <div class="toolbar">
      <el-button type="primary" @click="startCreatingFolder" :disabled="!selectedFolder">
        <i class="el-icon-folder-add"></i> 新建文件夹
      </el-button>
      <el-button type="danger" @click="deleteSelectedItem" :disabled="!selectedFolder">
        <i class="el-icon-delete"></i> 删除
      </el-button>
      <el-button type="info" @click="startRenamingFolder" :disabled="!selectedFolder">
        <i class="el-icon-edit"></i> 重命名
      </el-button>
      <el-button type="success" @click="openMoveDialog" :disabled="!selectedFolder">
        <i class="el-icon-refresh"></i> 移动到
      </el-button>
      <!-- 上传按钮 -->
      <el-button type="success" @click="handleUpload" :disabled="!selectedFolder || selectedFolder.type !== 'folder'">
        <i class="el-icon-upload"></i> 上传
      </el-button>
      <el-button
        type="primary"
        @click="downloadResource(selectedFolder)"
        :disabled="!selectedFolder || selectedFolder.type !== 'resource'"
      >
        <i class="el-icon-download"></i> 下载
      </el-button>

      <!-- 文件选择器隐藏，仅通过点击按钮触发 -->
      <input
        ref="fileInput"
        type="file"
        style="display: none;"
        @change="uploadFile"
      />
    </div>

    <!-- 树形结构 -->
    <el-tree
      :data="treeData"
      :props="defaultProps"
      default-expand-all
      node-key="id"
      :current-node-key="selectedFolder?.id"
      style="font-size: 20px;"
      class="custom-tree-node"
    >
      <template #default="{ node, data }">
        <div class="folder-node" @click.stop="toggleSelection(data)">
          <!-- 勾选框 -->
          <el-checkbox
            v-model="data.checked"
            @change="toggleSelection(data)"
            style="margin-right: 8px"
          />
          <!-- 图标 -->
          <el-icon v-if="data.type === 'folder'" style="margin-right: 8px">
            <Files />
          </el-icon>
          <el-icon v-else-if="data.type === 'resource'" style="margin-right: 8px">
            <Paperclip />
          </el-icon>
          <!-- 文件夹或资源名称 -->
          <span
            v-if="data.type === 'folder' && !data.editing"
            style="cursor: pointer; color: #000000;"
          >
        {{ data.label }}
      </span>
          <a
            v-else-if="data.type === 'resource'"
            class="resource-link"
            @click.prevent="downloadResource(data)"
          >
            {{ data.label }}
          </a>
          <!-- 文件名编辑输入框 -->
          <div v-else style="display: flex; align-items: center;">
            <el-input
              v-model="data.tempName"
              size="small"
              class="folder-input"
              placeholder="请输入文件夹名称"
              style="margin-right: 8px"
            ></el-input>
            <el-button
              size="mini"
              type="success"
              icon="el-icon-check"
              @click="confirmFolderAction(data)"
              style="margin-right: 4px"
            >
              确定
            </el-button>
            <el-button
              size="mini"
              type="danger"
              icon="el-icon-close"
              @click="cancelFolderAction(data)"
            >
              取消
            </el-button>
          </div>
        </div>
      </template>
    </el-tree>
    <!-- 移动到对话框 -->
    <el-dialog
      title="选择目标文件夹"
      v-model="moveDialogVisible"
      width="400px"
    >
      <el-tree
        :data="filteredTreeData"
        :props="defaultProps"
        node-key="id"
        default-expand-all
        :highlight-current="true"
        @node-click="selectTargetFolder"
      >
        <template #default="{ node, data }">
          <div class="folder-node">
            <i class="el-icon-folder" style="margin-right: 8px"></i>
            <span>{{ data.label }}</span>
          </div>
        </template>
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button @click="moveDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="confirmMove">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      treeData: [], // 树形结构数据
      defaultProps: {
        children: "children",
        label: "label",
      },
      selectedFolder: null, // 当前选中的文件夹或资源
      moveDialogVisible: false, // 是否显示移动对话框
      targetFolder: null, // 目标文件夹
      filteredTreeData: [], // 过滤后的移动框树形结构数据
    };
  },
  methods: {
    // 加载用户资源数据
    async loadUserResources() {
      try {
        this.loading = true;

        this.userId = localStorage.getItem("id");
        if (!this.userId) {
          this.$message.error("用户 ID 未找到，请登录后重试！");
          return;
        }

        const response = await fetch(`/resource/folders/tree?uid=${this.userId}`);
        const result = await response.json();

        if (result.code === "200") {
          const { folder, resources, children } = result.data;
          this.treeData = this.transformToTreeData(folder, resources, children);
        } else {
          this.$message.error(`加载资源失败：${result.message}`);
        }
      } catch (error) {
        console.error("加载资源失败：", error);
        this.$message.error("加载资源失败，请稍后重试！");
      } finally {
        this.loading = false;
      }
    },

    // 转换为树形结构
    transformToTreeData(folder, resources, children) {
      if (!folder) {
        console.error("数据格式错误：根节点 folder 不存在！");
        return [];
      }

      const rootNode = {
        id: folder.fno,
        label: folder.fname,
        type: "folder",
        checked: false,
        editing: false,
        actionType: null, // 新建或重命名的标志
        children: [],
      };

      const resourceNodes = resources.map((resource) => ({
        id: resource.sno,
        label: resource.sname,
        type: "resource",
        checked: false,
        size: resource.size,
        stype: resource.stype,
        path: resource.path,
      }));

      const buildChildren = (nodes) => {
        return nodes.map((child) => {
          const childFolder = child.folder;
          const childResources = child.resources || [];
          const childChildren = child.children || [];

          return {
            id: childFolder.fno,
            label: childFolder.fname,
            type: "folder",
            checked: false,
            editing: false,
            actionType: null, // 新建或重命名的标志
            children: [
              ...childResources.map((resource) => ({
                id: resource.sno,
                label: resource.sname,
                type: "resource",
                checked: false,
                size: resource.size,
                stype: resource.stype,
                path: resource.path,
              })),
              ...buildChildren(childChildren),
            ],
          };
        });
      };

      rootNode.children = [...resourceNodes, ...buildChildren(children)];
      return [rootNode];
    },

    toggleSelection(node) {
      node.checked = !node.checked;

      // 清除其他节点的选中状态
      this.clearAllChecked(this.treeData, node);

      // 更新当前选中文件夹或资源
      this.selectedFolder = node.checked ? node : null;

      console.log("Selected folder/resource updated:", this.selectedFolder);
    },


    // 清除其他节点的选中状态
    clearAllChecked(treeData, exceptNode) {
      treeData.forEach((item) => {
        if (item !== exceptNode) {
          item.checked = false;
        }
        if (item.children && item.children.length > 0) {
          this.clearAllChecked(item.children, exceptNode);
        }
      });
    },

    // 开始创建文件夹
    startCreatingFolder() {
      if (!this.selectedFolder) {
        this.$message.error("请先选择一个父文件夹！");
        return;
      }

      const parentFolder = this.selectedFolder;

      const newFolder = {
        id: Date.now().toString(),
        label: "",
        tempName: "新建文件夹",
        type: "folder",
        editing: true,
        actionType: "create", // 标记为新建操作
        parentFno: parentFolder.id,
        children: [],
      };

      if (!parentFolder.children) {
        parentFolder.children = [];
      }
      parentFolder.children.unshift(newFolder);
    },

    // 确定操作（新建或重命名）
    async confirmFolderAction(folder) {
      if (!folder.tempName.trim()) {
        this.$message.error("文件夹名称不能为空！");
        return;
      }

      try {
        if (folder.actionType === "create") {
          // 新建文件夹接口
          const formData = new FormData();
          formData.append("fno", folder.parentFno);
          formData.append("subFoldersName", folder.tempName);

          const response = await fetch(`/resource/folders/createFolder`, {
            method: "POST",
            body: formData,
          });
          const result = await response.json();

          if (result.code === "200") {
            this.$message.success("新建文件夹成功！");
            this.loadUserResources();
            this.clearSelection(); // 清除选中状态
          } else {
            this.$message.error(`新建失败：${result.message}`);
          }
        } else if (folder.actionType === "rename") {
          // 重命名接口
          const formData = new FormData();
          formData.append("fno", folder.id);
          formData.append("fname", folder.tempName);

          const response = await fetch(`/resource/folders/rename`, {
            method: "PUT",
            body: formData,
          });
          const result = await response.json();

          if (result.code === "200") {
            this.$message.success("重命名成功！");
            folder.label = folder.tempName; // 更新名称
            this.clearSelection(); // 清除选中状态
          } else {
            this.$message.error(`重命名失败：${result.message}`);
          }
        }
      } catch (error) {
        console.error("操作失败：", error);
        this.$message.error("操作失败，请稍后重试！");
      } finally {
        folder.editing = false;
        folder.actionType = null; // 清除操作类型
      }
    },
    // 取消操作
    cancelFolderAction(folder) {
      if (folder.actionType === "create") {
        // 如果是新建操作，删除节点
        const parentFolder = this.treeData.find((item) => item.id === folder.parentFno);
        if (parentFolder) {
          parentFolder.children = parentFolder.children.filter((item) => item.id !== folder.id);
        }
      } else if (folder.actionType === "rename") {
        // 如果是重命名操作，恢复原名称
        folder.tempName = folder.label;
      }

      folder.editing = false;
      folder.actionType = null;
    },
    // 下载资源
    async downloadResource(resource) {
      if (!resource || resource.type !== "resource") {
        this.$message.error("请选择要下载的资源！");
        return;
      }

      try {
        const downloadUrl = "/resource/sources/download";
        const formData = new FormData();
        formData.append("sno", resource.id);

        const response = await fetch(downloadUrl, {
          method: "POST",
          body: formData,
        });

        if (!response.ok) {
          throw new Error("下载失败！");
        }

        const blob = await response.blob();
        const link = document.createElement("a");
        const url = window.URL.createObjectURL(blob);
        link.href = url;
        link.download = resource.label || "downloaded-file";
        document.body.appendChild(link);
        link.click();
        window.URL.revokeObjectURL(url);
        document.body.removeChild(link);

        this.$message.success(`资源下载成功：${resource.label}`);
      } catch (error) {
        console.error("下载失败：", error);
        this.$message.error("文件下载失败，请稍后重试！");
      }
    },

    // 触发文件选择框
    handleUpload() {
      if (!this.selectedFolder || this.selectedFolder.type !== "folder") {
        this.$message.error("请先选择一个目标文件夹！");
        return;
      }
      this.$refs.fileInput.click(); // 打开文件选择框
    },

    // 上传文件逻辑
    async uploadFile(event) {
      const file = event.target.files[0]; // 获取选中的文件
      if (!file) {
        this.$message.error("请选择文件！");
        return;
      }

      if (!this.selectedFolder || this.selectedFolder.type !== "folder") {
        this.$message.error("请先选择一个目标文件夹！");
        return;
      }

      const folderFno = this.selectedFolder.id; // 获取目标文件夹 ID
      const formData = new FormData();
      formData.append("file", file); // 将文件添加到 FormData
      formData.append("fno", folderFno); // 指定目标文件夹 ID

      try {
        const response = await fetch("/resource/sources/upload", {
          method: "POST",
          body: formData,
        });

        const result = await response.json();

        if (result.code === "200") {
          this.$message.success("文件上传成功！");
          this.loadUserResources(); // 刷新资源结构
        } else {
          this.$message.error(`文件上传失败：${result.message}`);
        }
      } catch (error) {
        console.error("文件上传失败：", error);
        this.$message.error("文件上传失败，请稍后重试！");
      } finally {
        if (this.$refs.fileInput) {
          this.$refs.fileInput.value = ""; // 清空文件选择框
        }
      }
    },




    // 重命名选中的文件夹
    startRenamingFolder() {
      if (!this.selectedFolder) {
        this.$message.error("请先选择一个文件夹！");
        return;
      }

      this.selectedFolder.editing = true; // 切换到编辑模式
      this.selectedFolder.tempName = this.selectedFolder.label; // 设置临时名称
      this.selectedFolder.actionType = "rename"; // 标记为重命名操作
    },

    // 删除选中的文件夹或资源
    async deleteSelectedItem() {
      if (!this.selectedFolder) {
        this.$message.error("请先选择一个文件夹或资源！");
        return;
      }

      try {
        if (this.selectedFolder.type === "folder") {
          // 删除文件夹
          const response = await fetch(
            `/resource/folders/delete?fno=${this.selectedFolder.id}`,
            { method: "DELETE" }
          );
          const result = await response.json();

          if (result.code === "200") {
            this.$message.success("文件夹删除成功！");
            this.loadUserResources(); // 刷新树形结构
            this.clearSelection(); // 清除选中状态
          } else {
            this.$message.error(`删除文件夹失败：${result.message}`);
          }
        } else if (this.selectedFolder.type === "resource") {
          // 删除资源
          const formData = new FormData();
          formData.append("sno", this.selectedFolder.id);

          const response = await fetch(`/resource/sources/delete`, {
            method: "DELETE",
            body: formData,
          });
          const result = await response.json();

          if (result.code === "200") {
            this.$message.success("资源删除成功！");
            this.loadUserResources(); // 刷新树形结构
            this.clearSelection(); // 清除选中状态
          } else {
            this.$message.error(`删除资源失败：${result.message}`);
          }
        }
      } catch (error) {
        console.error("删除失败：", error);
        this.$message.error("删除失败，请稍后重试！");
      }
    },
    // 打开移动对话框
    openMoveDialog() {
      if (!this.selectedFolder) {
        this.$message.error("请先在主树中选择要移动的文件夹或资源！");
        return;
      }
      this.targetFolder = null; // 清空上一次选择
      this.filteredTreeData = this.filterTreeData(this.treeData, this.selectedFolder.id); // 过滤树形数据
      this.moveDialogVisible = true; // 打开对话框
    },

    // 过滤树形结构，排除源文件夹及其子文件夹
    filterTreeData(treeData, excludeId) {
      return treeData
        .filter((node) => node.id !== excludeId)
        .map((node) => {
          if (node.children && node.children.length > 0) {
            return {
              ...node,
              children: this.filterTreeData(node.children, excludeId),
            };
          }
          return { ...node };
        });
    },

    // 选择目标文件夹
    selectTargetFolder(node) {
      if (!node || node.type !== "folder") {
        this.$message.warning("请选择文件夹作为目标！");
        this.targetFolder = null;
        return;
      }
      this.targetFolder = node; // 记录目标文件夹
      this.$message.info(`目标文件夹已选中：${node.label}`);
    },

    // 确认移动
    async confirmMove() {
      if (!this.selectedFolder) {
        this.$message.error("请先在主树中选择要移动的文件夹或资源！");
        return;
      }
      if (!this.targetFolder) {
        this.$message.error("请在移动对话框中选择目标文件夹！");
        return;
      }

      try {
        if (this.selectedFolder.type === "folder") {
          // 移动文件夹
          const formData = new FormData();
          formData.append("folderFno", this.selectedFolder.id);
          formData.append("newParentFno", this.targetFolder.id);

          const response = await fetch(`/resource/folders/move`, {
            method: "PUT",
            body: formData,
          });

          const result = await response.json();
          if (result.code === "200") {
            this.$message.success("文件夹移动成功！");
            this.loadUserResources(); // 刷新主树形结构
          } else {
            this.$message.error(`文件夹移动失败：${result.message}`);
          }
        } else if (this.selectedFolder.type === "resource") {
          // 移动资源
          const formData = new FormData();
          formData.append("sno", this.selectedFolder.id);
          formData.append("newFno", this.targetFolder.id);

          const response = await fetch(`/resource/sources/move`, {
            method: "PUT",
            body: formData,
          });

          const result = await response.json();
          if (result.code === "200") {
            this.$message.success("资源移动成功！");
            this.loadUserResources(); // 刷新主树形结构
          } else {
            this.$message.error(`资源移动失败：${result.message}`);
          }
        }
      } catch (error) {
        console.error("移动失败：", error);
        this.$message.error("移动失败，请稍后重试！");
      } finally {
        this.moveDialogVisible = false; // 关闭对话框
      }
    },

    clearSelection() {
      this.clearAllChecked(this.treeData); // 清空所有节点的选中状态
      this.selectedFolder = null; // 重置当前选中的文件夹或资源
    },
  },

  mounted() {
    this.loadUserResources();
  },
};
</script>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  padding: 20px;
}

.toolbar {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.folder-node {
  display: flex;
  align-items: center;
  cursor: pointer; /* 添加鼠标指针 */
}

.folder-input {
  width: 200px;
  margin-right: 10px;
}

.resource-link {
  color: #1890ff; /* 蓝色文字 */
  text-decoration: underline;
  cursor: pointer; /* 鼠标手势 */
}

.custom-tree-node :deep(.el-tree-node) {
  margin-bottom: 8px;
}
.resource-link:hover {
  color: #40a9ff; /* 悬停时的文字颜色 */
}
</style>
